/*

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

*/
module derelict.sdl2.image;

private
{
    import derelict.util.loader;
    import derelict.util.exception;
    import derelict.util.system;
    import derelict.sdl2.types;
    import derelict.sdl2.functions;

    static if(Derelict_OS_Windows)
        enum libNames = "SDL2_image.dll";
    else static if(Derelict_OS_Mac)
        enum libNames = "../Frameworks/SDL2_image.framework/SDL2_image, /Library/Frameworks/SDL2_image.framework/SDL2_image, /System/Library/Frameworks/SDL2_image.framework/SDL2_image";
    else static if(Derelict_OS_Posix)
        enum libNames = "libSDL2_image.so, libSDL2_image-2.0.so, libSDL2_image-2.0.so.0, /usr/local/lib/libSDL2_image.so, /usr/local/lib/libSDL2_image-2.0.so, /usr/local/lib/libSDL2_image-2.0.so.0";
    else
        static assert(0, "Need to implement SDL2_image libNames for this operating system.");
}

alias SDL_SetError IMG_SetError;
alias SDL_GetError IMG_GetError;

enum : Uint8
{
    SDL_IMAGE_MAJOR_VERSION     = 2,
    SDL_IMAGE_MINOR_VERSION     = 0,
    SDL_IMAGE_PATCHLEVEL        = 0,
}

void SDL_IMAGE_VERSION(SDL_version* X)
{
    X.major     = SDL_IMAGE_MAJOR_VERSION;
    X.minor     = SDL_IMAGE_MINOR_VERSION;
    X.patch     = SDL_IMAGE_PATCHLEVEL;
}

enum
{
    IMG_INIT_JPG    = 0x00000001,
    IMG_INIT_PNG    = 0x00000002,
    IMG_INIT_TIF    = 0x00000004,
    IMG_INIT_WEBP   = 0x00000008,
}



extern(C)
{
    alias nothrow int function(int) da_IMG_Init;
    alias nothrow int function() da_IMG_Quit;
    alias nothrow const(SDL_version)* function() da_IMG_Linked_Version;
    alias nothrow SDL_Surface* function(SDL_RWops*, int, const(char)*) da_IMG_LoadTyped_RW;
    alias nothrow SDL_Surface* function(const(char)*) da_IMG_Load;
    alias nothrow SDL_Surface* function(SDL_RWops*, int) da_IMG_Load_RW;

    alias nothrow SDL_Texture* function(SDL_Renderer*, const(char)*) da_IMG_LoadTexture;
    alias nothrow SDL_Texture* function(SDL_Renderer*, SDL_RWops*, int) da_IMG_LoadTexture_RW;
    alias nothrow SDL_Texture* function(SDL_Renderer*, SDL_RWops*, int, const(char)*) da_IMG_LoadTextureTyped_RW;

    alias nothrow int function(SDL_RWops*) da_IMG_isICO;
    alias nothrow int function(SDL_RWops*) da_IMG_isCUR;
    alias nothrow int function(SDL_RWops*) da_IMG_isBMP;
    alias nothrow int function(SDL_RWops*) da_IMG_isGIF;
    alias nothrow int function(SDL_RWops*) da_IMG_isJPG;
    alias nothrow int function(SDL_RWops*) da_IMG_isLBM;
    alias nothrow int function(SDL_RWops*) da_IMG_isPCX;
    alias nothrow int function(SDL_RWops*) da_IMG_isPNG;
    alias nothrow int function(SDL_RWops*) da_IMG_isPNM;
    alias nothrow int function(SDL_RWops*) da_IMG_isTIF;
    alias nothrow int function(SDL_RWops*) da_IMG_isXCF;
    alias nothrow int function(SDL_RWops*) da_IMG_isXPM;
    alias nothrow int function(SDL_RWops*) da_IMG_isXV;
    alias nothrow int function(SDL_RWops*) da_IMG_isWEBP;

    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadICO_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadCUR_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadBMP_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadGIF_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadJPG_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadLBM_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadPCX_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadPNG_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadPNM_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadTGA_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadTIF_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadXCF_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadXPM_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadXV_RW;
    alias nothrow SDL_Surface* function(SDL_RWops*) da_IMG_LoadWEBP_RW;

    alias nothrow SDL_Surface* function(char**) da_IMG_ReadXPMFromArray;
}

__gshared
{
    da_IMG_Init IMG_Init;
    da_IMG_Quit IMG_Quit;
    da_IMG_Linked_Version IMG_Linked_Version;
    da_IMG_LoadTyped_RW IMG_LoadTyped_RW;
    da_IMG_Load IMG_Load;
    da_IMG_Load_RW IMG_Load_RW;
    da_IMG_LoadTexture IMG_LoadTexture;
    da_IMG_LoadTexture_RW IMG_LoadTexture_RW;
    da_IMG_LoadTextureTyped_RW IMG_LoadTextureTyped_RW;
    da_IMG_isICO IMG_isICO;
    da_IMG_isCUR IMG_isCUR;
    da_IMG_isBMP IMG_isBMP;
    da_IMG_isGIF IMG_isGIF;
    da_IMG_isJPG IMG_isJPG;
    da_IMG_isLBM IMG_isLBM;
    da_IMG_isPCX IMG_isPCX;
    da_IMG_isPNG IMG_isPNG;
    da_IMG_isPNM IMG_isPNM;
    da_IMG_isTIF IMG_isTIF;
    da_IMG_isXCF IMG_isXCF;
    da_IMG_isXPM IMG_isXPM;
    da_IMG_isXV IMG_isXV;
    da_IMG_isWEBP IMG_isWEBP;
    da_IMG_LoadICO_RW IMG_LoadICO_RW;
    da_IMG_LoadCUR_RW IMG_LoadCUR_RW;
    da_IMG_LoadBMP_RW IMG_LoadBMP_RW;
    da_IMG_LoadGIF_RW IMG_LoadGIF_RW;
    da_IMG_LoadJPG_RW IMG_LoadJPG_RW;
    da_IMG_LoadLBM_RW IMG_LoadLBM_RW;
    da_IMG_LoadPCX_RW IMG_LoadPCX_RW;
    da_IMG_LoadPNG_RW IMG_LoadPNG_RW;
    da_IMG_LoadPNM_RW IMG_LoadPNM_RW;
    da_IMG_LoadTGA_RW IMG_LoadTGA_RW;
    da_IMG_LoadTIF_RW IMG_LoadTIF_RW;
    da_IMG_LoadXCF_RW IMG_LoadXCF_RW;
    da_IMG_LoadXPM_RW IMG_LoadXPM_RW;
    da_IMG_LoadXV_RW IMG_LoadXV_RW;
    da_IMG_LoadWEBP_RW IMG_LoadWEBP_RW;
    da_IMG_ReadXPMFromArray IMG_ReadXPMFromArray;
}

class DerelictSDL2ImageLoader : SharedLibLoader
{

    protected
    {
        override void loadSymbols()
        {
            bindFunc(cast(void**)&IMG_Init, "IMG_Init");
            bindFunc(cast(void**)&IMG_Quit, "IMG_Quit");
            bindFunc(cast(void**)&IMG_Linked_Version, "IMG_Linked_Version");
            bindFunc(cast(void**)&IMG_LoadTyped_RW, "IMG_LoadTyped_RW");
            bindFunc(cast(void**)&IMG_Load, "IMG_Load");
            bindFunc(cast(void**)&IMG_Load_RW, "IMG_Load_RW");
            bindFunc(cast(void**)&IMG_LoadTexture, "IMG_LoadTexture");
            bindFunc(cast(void**)&IMG_LoadTexture_RW, "IMG_LoadTexture_RW");
            bindFunc(cast(void**)&IMG_LoadTextureTyped_RW, "IMG_LoadTextureTyped_RW");
            bindFunc(cast(void**)&IMG_isICO, "IMG_isICO");
            bindFunc(cast(void**)&IMG_isCUR, "IMG_isCUR");
            bindFunc(cast(void**)&IMG_isBMP, "IMG_isBMP");
            bindFunc(cast(void**)&IMG_isGIF, "IMG_isGIF");
            bindFunc(cast(void**)&IMG_isJPG, "IMG_isJPG");
            bindFunc(cast(void**)&IMG_isLBM, "IMG_isLBM");
            bindFunc(cast(void**)&IMG_isPCX, "IMG_isPCX");
            bindFunc(cast(void**)&IMG_isPNG, "IMG_isPNG");
            bindFunc(cast(void**)&IMG_isPNM, "IMG_isPNM");
            bindFunc(cast(void**)&IMG_isTIF, "IMG_isTIF");
            bindFunc(cast(void**)&IMG_isXCF, "IMG_isXCF");
            bindFunc(cast(void**)&IMG_isXPM, "IMG_isXPM");
            bindFunc(cast(void**)&IMG_isXV, "IMG_isXV");
            bindFunc(cast(void**)&IMG_isWEBP, "IMG_isWEBP");
            bindFunc(cast(void**)&IMG_LoadICO_RW, "IMG_LoadICO_RW");
            bindFunc(cast(void**)&IMG_LoadCUR_RW, "IMG_LoadCUR_RW");
            bindFunc(cast(void**)&IMG_LoadBMP_RW, "IMG_LoadBMP_RW");
            bindFunc(cast(void**)&IMG_LoadGIF_RW, "IMG_LoadGIF_RW");
            bindFunc(cast(void**)&IMG_LoadJPG_RW, "IMG_LoadJPG_RW");
            bindFunc(cast(void**)&IMG_LoadLBM_RW, "IMG_LoadLBM_RW");
            bindFunc(cast(void**)&IMG_LoadPCX_RW, "IMG_LoadPCX_RW");
            bindFunc(cast(void**)&IMG_LoadPNG_RW, "IMG_LoadPNG_RW");
            bindFunc(cast(void**)&IMG_LoadPNM_RW, "IMG_LoadPNM_RW");
            bindFunc(cast(void**)&IMG_LoadTGA_RW, "IMG_LoadTGA_RW");
            bindFunc(cast(void**)&IMG_LoadTIF_RW, "IMG_LoadTIF_RW");
            bindFunc(cast(void**)&IMG_LoadXCF_RW, "IMG_LoadXCF_RW");
            bindFunc(cast(void**)&IMG_LoadXPM_RW, "IMG_LoadXPM_RW");
            bindFunc(cast(void**)&IMG_LoadXV_RW, "IMG_LoadXV_RW");
            bindFunc(cast(void**)&IMG_isXV, "IMG_isXV");
            bindFunc(cast(void**)&IMG_LoadWEBP_RW, "IMG_LoadWEBP_RW");
        }
    }

    public
    {
        this()
        {
            super(libNames);
        }
    }
}

__gshared DerelictSDL2ImageLoader DerelictSDL2Image;

shared static this()
{
    DerelictSDL2Image = new DerelictSDL2ImageLoader();
}

shared static ~this()
{
    DerelictSDL2Image.unload();
}